/*
This file is part of Docking@Home.
http://docking.gcl.cis.udel.edu
Copyright (C) 2009 University of Delaware

Docking@Home is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Docking@Home is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Docking@Home.  If not, see <http://www.gnu.org/licenses/>.
*/
/*
	Filename: VectorMath.h
	Description: Contains all mathematical operations required for vector
		operations in this program. Vectors are stored as 3 element float arrays.
	Revision History: 
		Created - 11/06/07
	Author: Robert Keller (11/06/07 -> Current)
*/

#ifndef _VectorMath_h
#define _VectorMath_h

#include <math.h>

/*
Name: vectorSubtraction
Description: Subtracts one vector from another
Params:	vec1,	the first vector
		vec2,	the second vector
		ans,	result of vec1 - vec2
Returns: float ans[3], the resulting vector from the subtraction
*/
void vectorSubtraction(float vec1[3], float vec2[3], float ans[3])
{
	ans[0] = vec1[0] - vec2[0];
	ans[1] = vec1[1] - vec2[1];
	ans[2] = vec1[2] - vec2[2];
}// vectorSubtraction

/*
Name: vectorAddition
Description: Adds one vector to another
Params:	vec1,	the first vector
		vec2,	the second vector
		ans,	result of vec1 + vec2
Returns: float ans[3], the resulting vector from the addition
*/
void vectorAddition(float vec1[3], float vec2[3], float ans[3])
{
	ans[0] = vec1[0] + vec2[0];
	ans[1] = vec1[1] + vec2[1];
	ans[2] = vec1[2] + vec2[2];
}// vectorAddition

/*
Name: distanceBetweenVectors
Description: Determines the length of the subtraction vector between
	the two supplied vectors. This yields the distance between their 
	endpoints.
Params:	vec1,	the first vector
		vec2,	the second vector
Returns: float, the distance between the two vector's
*/
float distanceBetweenVectors(float vec1[3], float vec2[3])
{
	float subtract [3];
	vectorSubtraction(vec1, vec2, subtract);

	return sqrt(subtract[0]*subtract[0] + subtract[1]*subtract[1]
		+ subtract[2]*subtract[2]);
}// distanceBetweenVectors

/*
Name: vectorNormalize 
Description: Normalizes a vector (makes it a unit vector)
Params:	vec,	the vector
Postconditions: The input vector is now a unit vector
Returns: void
*/
void vectorNormalize (float vec[3])
{
	float mag = sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
	if(mag!=0)  {
		vec[0]/=mag;
		vec[1]/=mag;
		vec[2]/=mag;
    } else {
		vec[0]=0;
		vec[1]=0;
		vec[2]=0;
	}
}// vectorNormalize

/*
Name: dotProduct
Description: Takes the dot product of two vectors. This will determine
	the cosine of the angle between two vectors.
Params:	vec1,	the first vector
		vec2,	the second vector
Returns: float, the cosine of the angle between the two vectors
*/
float dotProduct(float vec1[3], float vec2[3])
{
	return vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2];
}// dotProduct

/*
Name: crossProduct
Description: Takes the cross product of two vectors. This will 
	find a vector that is perpindicular to the other two
Params:	vec1,	the first vector
		vec2,	the second vector
		ans,	the resulting perpindicular vector
Returns: void
*/
void crossProduct (float vec1[2], float vec2[3], float ans[3])
{
	ans[0] = vec1[1]*vec2[2] - vec1[2]*vec2[1];
	ans[1] = vec1[2]*vec2[0] - vec1[0]*vec2[2];
	ans[2] = vec1[0]*vec2[1] - vec1[1]*vec2[0];
}// crossProduct

/*
Name: crossProductNormalized
Description: Takes the cross product of two vectors and normalizes the answer.
	This will find a unit vector that is perpindicular to the other two.
Params:	vec1,	the first vector
		vec2,	the second vector
		ans,	the resulting perpindicular vector
Returns: void
*/
void crossProductNormalized (float vec1[2], float vec2[3], float ans[3])
{
	crossProduct(vec1, vec2, ans);

	vectorNormalize(ans);
}// crossProductNormalized

#endif
